package com.kwok.ssm.springmvc.controller;

import com.kwok.ssm.springmvc.entity.User;
import com.kwok.ssm.springmvc.entity.UserList;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

@Controller
@RequestMapping("/user")
@ResponseBody
@SessionAttributes({"id", "name", "birthday", "gender"})
public class UserController {

    @RequestMapping("/test")
    public String test() {
        System.out.println("UserController.test");
        return "UserTest";
    }

    // 变量收参
    @RequestMapping("/params")
    public String params(Integer id, String name, @DateTimeFormat(pattern = "yyyy-MM-dd") Date birthday) {
        System.out.println("接收到前端输入的参数id：" + id);
        System.out.println("接收到前端输入的参数name：" + name);
        System.out.println("接收到前端输入的参数birthday：" + birthday);
        return "UserTest";
    }

    // 实体收参
    @RequestMapping("/entity")
    public String entity(User user) {
        System.out.println("接收到前端输入的实体user：" + user);
        return "UserTest";
    }

    // 数组收参
    @RequestMapping("/array")
    public String array(String[] hobbies) {
        System.out.println("接收到前端输入的数组：" + Arrays.toString(hobbies));
        return "UserTest";
    }

    // 集合收参
    @RequestMapping("/list")
    public String list(UserList userList) {
        for (User user:userList.getUserList()) {
            System.out.println("接收到前端输入的实体user：" + user);
        }
        return "UserTest";
    }

    // 路径收参
    /**
     * 当路径名{pathName}和属性名一致时，直接使用@PathVariable接收即可，("id")可省略不写
     * @param id
     * @return
     */
    @RequestMapping("/pathOne/{id}")
    public String pathId(@PathVariable Integer id) {
        System.out.println("接收到前端输入的参数id：" + id);
        return "UserTest";
    }

    /**
     * 当路径名{pathName}和属性名不一致时，使用@PathVariable("name")接收，("name")不可省略，表示把前端路径参数{name}的值赋给形参username
     * @param username
     * @return
     */
    @RequestMapping("/pathTwo/{name}")
    public String pathName(@PathVariable("name") String username) {
        System.out.println("接收到前端输入的参数name，并赋值给后端形参username：" + username);
        return "UserTest";
    }

    /**
     * 当接收的参数类型是java.util.Date类型时，必须加上注解@DateTimeFormat(pattern = "yyyy-MM-dd")，且日期格式不能是Spring MVC框架默认的yyyy/MM/dd（会报404），必须是yyyy-MM-dd
     * @param birthday
     * @return
     */
    @RequestMapping("/pathThree/{birthday}")
    public String pathBirthday(@PathVariable("birthday") @DateTimeFormat(pattern = "yyyy-MM-dd") Date birthday) {
        System.out.println("接收到前端输入的参数birthday：" + birthday);
        return "UserTest";
    }

    // 中文收参
    @RequestMapping("/chinese")
    public String chinese(String chineseWord) {
        System.out.println("接收到前端输入的参数chineseWord：" + chineseWord);
        return "UserTest";
    }

    // 请求方式
    // 请求转发
    // 页面转发 - 和视图解析器无关
    @RequestMapping("/forwardPage")
    public String forwardPage() {
        System.out.println("页面转发");
        return "forward:/jsp/PostRequestChineseTest.jsp";
    }

    // 控制器转发
    @RequestMapping("/forwardController")
    public String forwardController() {
        System.out.println("控制器转发");
        return "forward:/user/test";
    }

    // 重定向
    @RequestMapping("/redirectPage")
    public String redirectPage() {
        System.out.println("页面重定向");
        return "redirect:/jsp/PostRequestChineseTest.jsp";
    }

    @RequestMapping("/redirectController")
    public String redirectController() {
        System.out.println("控制器重定向");
        return "redirect:/user/test";
    }

    // 传值
    // request传值
    @RequestMapping("/requestScope")
    public String requestScope(HttpServletRequest request, Integer id, String name, Date birthday, Byte gender) {
        System.out.println("UserController.requestScope");
        request.setAttribute("id", 1);
        request.setAttribute("name", "张三");
        // 如果是request.setAttribute("birthday", "1999/01/01")，则前端接收的是1999/01/01，且不能用<fmt/>标签格式化日期
        // 如果是request.setAttribute("birthday", new Date("1999/01/01"))，则前端接收的是Fri Jan 01 00:00:00 CST 1999，可以用<fmt/>标签格式化日期
        request.setAttribute("birthday", new Date("1999/01/01"));
        request.setAttribute("gender", 1);
        return "UserTest";
    }

    // session传值
    @RequestMapping("/sessionScope")
    public String sessionScope(HttpSession session, Integer id, String name, Date birthday, Byte gender) {
        System.out.println("UserController.sessionScope");
        session.setAttribute("id", 2);
        session.setAttribute("name", "李四");
        session.setAttribute("birthday", new Date("2000/01/01"));
        session.setAttribute("gender", 2);
        return "UserTest";
    }

    // model传值,model和request都是将值存入requestScope中
    @RequestMapping("/model")
    public String model(Model model, Integer id, String name, Date birthday, Byte gender) {
        System.out.println("UserController.modelScope");
        model.addAttribute("id", 3);
        model.addAttribute("name", "王五");
        model.addAttribute("birthday", new Date("2001/01/01"));
        model.addAttribute("gender", 1);
        return "UserTest";
    }

    // ModelAndView传值,modelAndView也是将值存入requestScope中
    @RequestMapping("/mav")
    public ModelAndView mav(Integer id, String name, Date birthday, Byte gender) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("id", 4);
        modelAndView.addObject("name", "独孤求败");
        modelAndView.addObject("birthday", new Date("2002/01/01"));
        modelAndView.addObject("gender", 1);
        modelAndView.setViewName("UserTest");
        return modelAndView;
    }

    // 移除使用@SessionAttributes({"id", "name", "birthday", "gender"})注解存入sessionScope中的值
    @RequestMapping("/remove")
    public String removeSessionScope(SessionStatus sessionStatus) {
        sessionStatus.setComplete();
        return "UserTest";
    }

    // 如果后端返回给前端的是字符串，则无需再转为json，不需要添加jackson-databind依赖，前端可以直接接收
    @RequestMapping(value = "/jsonString", produces = {"text/html;charset=UTF-8"})
    @ResponseBody
    public String jsonStringTest() {
        System.out.println("UserController.jsonTest");
        return "你好，世界！";
    }

    // 如果后端返回给前端的是对象，则必须转为json（对象转json数据需要添加jackson-databind依赖），前端才能接收
    @RequestMapping(value = "/jsonObject", produces = {"application/json;charset=UTF-8"}) //相当于@RequestMapping("/jsonObject")
    // @ResponseBody的作用：将后端返回的内容(对象，集合等)转为json数据返回给前端；@RequestBody的作用：将前端传过来的json数据转为对象，从而能被形参中的对象自然接收
    // 写法一
    @ResponseBody
    public User jsonObjectTest() {
        User user = new User()
                .setId(1001)
                .setName("Kwok")
                .setBirthday(new Date("1999/01/01"));
        return user;
    }

    @RequestMapping("/jsonObjectTwo")
    // 写法二
    public @ResponseBody User jsonObjectTwoTest() {
        User user = new User()
                .setId(1002)
                .setName("郭同志")
                .setBirthday(new Date("1999/12/31"));
        return user;
    }

    // 后端返回给前端的是一个集合
    @RequestMapping("/jsonList")
    public @ResponseBody List<User> jsonListTest() {
        User user1 = new User()
                .setId(1)
                .setName("李华")
                .setBirthday(new Date("1995/01/01"));
        User user2 = new User()
                .setId(2)
                .setName("李明")
                .setBirthday(new Date("1996/01/01"));
        List<User> userList = new ArrayList<User>();
        userList.add(user1);
        userList.add(user2);
        return userList;
    }

    @RequestMapping("/jsonObjectThree")
    public String jsonObjectThree(@RequestBody User user) {
        System.out.println(user);
        return "OK";
    }

    @RequestMapping(value = "/jsonObjectFour")
    public String jsonObjectFour(User user) {
        System.out.println(user);
        return "OK";
    }

    @RequestMapping("/exceptionResolver")
    public String jsonObjectFour() {
        System.out.println("UserController.exceptionResolver");
        int i = 1 / 0;
        System.out.println("出现了算数异常");
        return "没有出现异常";
    }

    @RequestMapping("/login")
    public String login(HttpSession session, String captcha) {
        System.out.println("进入登录的handler...");

        System.out.println("前端输入的验证码：" + captcha);
        //获取生成的验证码
        String kaptcha = (String) session.getAttribute("kaptcha");
        System.out.println("kaptcha生成的验证码：" + kaptcha);

        if (! captcha.equals(kaptcha)) {
            return "code error";
        }

        // 设置登录凭证
        session.setAttribute("username", "Kwok");
        return "Login Success!";
    }

}
